命令模式

定义命令模式

将请求封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

现实世界中任何一个稍微复杂的子系统都应当有一套命令,比如餐馆的运行机制:
顾客A来到餐馆点一碗面(发出请求) -> 柜台服务员记录下来(创建命令) -> 服务员把小票扔给厨房 -> 厨师C很快做好了一碗面(请求被执行)
顾客不知道将由谁来做这碗面,柜台服务员也不知道,厨师不知道是谁点了这碗面,只知道做完面就可以休息了

是不是与命令模式很相像?

不妨用代码来实现上面的机制

首先,我们需要一个命令接口,毕竟命令才是命令模式的核心,没有命令,一切都是空想

1
2
3
4
5
6
7
8
package CommandPattern;

/**
* 定义Command接口
*/
public interface Command {
public abstract void execute(); //只需要定义一个统一的执行方法
}

有了命令还需要执行者,否则只有将军没有小兵,餐馆的执行者当然是厨师:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package CommandPattern;

/**
* 定义Chef基类
*/
public abstract class Chef {
//在此定义厨师的公共属性

/**
* 定义烹饪方法
*/
public abstract void cook();
//在此定义其它有用的方法
}

我们还需要实现具体的厨师,术业有专攻:
做面的厨师:

1
2
3
4
5
6
7
8
9
10
11
12
package CommandPattern;

/**
* 定义专业做面的厨师
*/
public class NoodlesChef extends Chef{

@Override
public void cook() {
System.out.println("做好了一碗美味的拉面");
}
}

做饼的厨师:

1
2
3
4
5
6
7
8
9
10
11
12
package CommandPattern;

/**
* 定义专业做饼的厨师
*/
public class PieChef extends Chef{

@Override
public void cook() {
System.out.println("做好了一块香喷喷的大饼");
}
}

有了小兵,有了将军,我们还需要一套完整的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package CommandPattern;

/**
* 实现具体NoodlesCommand
*/
public class NoodlesCommand implements Command{
private NoodlesChef chef;//专业做面的厨师

public NoodlesCommand(){
chef = new NoodlesChef();
}

@Override
public void execute() {
chef.cook();
//调用其它需要的方法
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package CommandPattern;

/**
* 实现具体PieCommand
*/
public class PieCommand implements Command{
private PieChef chef;//专业做饼的厨师

public PieCommand(){
chef = new PieChef();
}

@Override
public void execute() {
chef.cook();
//调用其它需要的方法
}
}

准备工作做好了,餐馆可以开张了
三.效果示例
需要一个Test类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package CommandPattern;

/**
* 实现测试类
*/
public class Test {

public static void main(String[] args) {
System.out.println("Command Pattern餐馆开张。。");
System.out.println("第一位客户X先生");
System.out.println("X先生:你好,我需要一碗面,我饿极了");
NoodlesCommand nCmd = new NoodlesCommand();
System.out.println("柜台服务员:好的,我已经记下了,马上就好");
System.out.println("柜台服务员:厨房~~,接单");
nCmd.execute();
System.out.println("X先生:真快啊!");

System.out.println();

System.out.println("第二位客户XX先生");
System.out.println("XX先生:你好,我需要一块饼,20分钟后来取");
PieCommand pCmd = new PieCommand();
System.out.println("柜台服务员:好的,我已经记下了");
System.out.println("15分钟后");
System.out.println("柜台服务员:厨房~~,接单");
pCmd.execute();
System.out.println("XX先生:真准时啊!");
}
}

结果示例: